﻿using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Geodatabase;
using System.IO;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyMap
{
    public partial class MyMap : Form
    {
        public MyMap()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);  // 此代码不添加的话运行会有错误
            InitializeComponent();
        }

        private void MyMap_Load(object sender, EventArgs e)
        {

        }

        

        private void AddVectorlayer(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "shapefile文件（*.shp）|*.shp";

            DialogResult dialogResult = openFileDialog.ShowDialog();
            if (dialogResult != DialogResult.OK)
            {
                return;
            }

            string path = openFileDialog.FileName;
            string folder = System.IO.Path.GetDirectoryName(path);
            string fileName = System.IO.Path.GetFileName(path);

            IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspace workspace = workspaceFactory.OpenFromFile(folder, 0);
            if (workspace == null)
            {
                MessageBox.Show("无法打开该工作空间！");
                return;
            }
            IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(fileName);
            if (featureClass == null)
            {
                MessageBox.Show("无法打开该矢量数据集！");
                return;
            }
            IFeatureLayer featureLayer = new FeatureLayerClass();
            featureLayer.FeatureClass = featureClass;
            featureLayer.Name = featureClass.AliasName;
            ILayer layer = featureLayer as ILayer;
            axMapControl1.Map.AddLayer(layer);
            axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

    

    private void AddRasterlayer(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            // 支持常见栅格格式：TIFF、JPG、PNG、BMP、GRID等
            openFileDialog.Filter = "栅格文件|*.tif;*.tiff;*.jpg;*.jpeg;*.png;*.bmp;*.img;*.grid|所有文件|*.*";

            DialogResult dialogResult = openFileDialog.ShowDialog();
            if (dialogResult != DialogResult.OK)
            {
                return;
            }

            string filePath = openFileDialog.FileName;
            string folderPath = System.IO.Path.GetDirectoryName(filePath);
            string fileName = System.IO.Path.GetFileName(filePath);

            try
            {
                // 创建栅格工作空间工厂
                IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass();
                IWorkspace workspace = workspaceFactory.OpenFromFile(folderPath, 0);
                if (workspace == null)
                {
                    MessageBox.Show("无法打开栅格工作空间！");
                    return;
                }

                // 转换为栅格工作空间并打开栅格数据集
                IRasterWorkspace rasterWorkspace = workspace as IRasterWorkspace;
                IRasterDataset rasterDataset = rasterWorkspace.OpenRasterDataset(fileName);
                if (rasterDataset == null)
                {
                    MessageBox.Show("无法打开该栅格数据集！");
                    return;
                }

                // 创建栅格图层并设置属性
                IRasterLayer rasterLayer = new RasterLayerClass();
                rasterLayer.CreateFromDataset(rasterDataset);

                // 添加到地图控件并刷新视图
                ILayer layer = rasterLayer as ILayer;
                axMapControl1.Map.AddLayer(layer);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加栅格图层失败：{ex.Message}");
            }
        }

        private void defineSimpleRender(IFeatureLayer featureLayer)
        {
            IRgbColor color = new RgbColor();
            color.Red = 255;
            color.Blue = 0;
            color.Green = 0;

            // 设置用于渲染的符号的基本属性（面状符号）
            ISimpleFillSymbol simpleFeatureSymbol = new SimpleFillSymbol();
            simpleFeatureSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
            simpleFeatureSymbol.Outline.Width = 0.4;
            simpleFeatureSymbol.Color = color as IColor;

            // 设置简单渲染的相关属性
            ISimpleRenderer simpleRenderer = new SimpleRendererClass();
            simpleRenderer.Symbol = simpleFeatureSymbol as ISymbol;

            // 接口转换，对渲染方式进行设置
            IGeoFeatureLayer geoFeatureLayer = featureLayer as IGeoFeatureLayer;
            geoFeatureLayer.Renderer = simpleRenderer as IFeatureRenderer;

            // 地图刷新
            axMapControl1.Refresh();
        }

        private void Simplerendering(object sender, EventArgs e)
        {
            esriTOCControlItem tocChoosedItem = esriTOCControlItem.esriTOCControlItemLayer;
            IBasicMap basicMap = null;
            ILayer tocChoosedLayer = null;
            object other = new object();
            object index = new object();
            axTOCControl1.GetSelectedItem(
                ref tocChoosedItem,
                ref basicMap,
                ref tocChoosedLayer,
                ref other,
                ref index
            );

            if (tocChoosedLayer is IFeatureLayer)
            {
                defineSimpleRender(tocChoosedLayer as IFeatureLayer);
            }
            else
            {
                MessageBox.Show("未选择图层，或者图层非矢量图层！");
                return;
            }
        }

        private void defineUniqueValueRender(IFeatureLayer featureLayer, string fieldName)
        {
            // 设置颜色列表，用于随机生成颜色（用于填充面状要素）
            // 设置颜色的基本属性，包括色调（H）、饱和度（S）以及亮度（V）
            IRandomColorRamp colorRamp = new RandomColorRamp();
            colorRamp.StartHue = 76;
            colorRamp.EndHue = 188;
            colorRamp.MinSaturation = 20;
            colorRamp.MaxSaturation = 40;
            colorRamp.MinValue = 85;
            colorRamp.MaxValue = 100;

            colorRamp.UseSeed = true;
            colorRamp.Seed = 43;

            // 设置唯一值渲染的相关属性
            IUniqueValueRenderer valueRender = new UniqueValueRenderer();
            valueRender.FieldCount = 1;
            valueRender.set_Field(0, fieldName);

            // 遍历要素类的所有要素，并为每个要素设置基本的渲染样式
            IFeatureClass featureClass = featureLayer.FeatureClass;
            IFeatureCursor featureCursor = featureClass.Search(null, false);
            IFeature feature = featureCursor.NextFeature();

            // 获取指定字段的索引值
            IFields fields = featureCursor.Fields;
            // 存储字段的索引值
            int iFieldIndex = fields.FindField(fieldName);

            // 为不同的要素，设置不同的填充颜色
            colorRamp.Size = featureClass.FeatureCount(null);
            bool bOK;
            // 判断随机颜色生成是否成功
            colorRamp.CreateRamp(out bOK);

            // 获得随机生成的颜色列表
            IEnumColors enumColors = colorRamp.Colors;
            enumColors.Reset();
            IColor color = enumColors.Next();

            // 开始遍历，为每个要素设置基本的渲染信息
            while (feature != null)
            {
                // 为每个要素设置基本的渲染符号
                ISimpleFillSymbol simpleFillFeature = new SimpleFillSymbolClass();
                simpleFillFeature.Style = esriSimpleFillStyle.esriSFSSolid;
                simpleFillFeature.Outline.Width = 0.4;
                simpleFillFeature.Color = color;

                // 获得当前要素中指定字段的名称
                string featureName = Convert.ToString(feature.get_Value(iFieldIndex));

                // 设置唯一值渲染的相关属性
                valueRender.AddValue(featureName, fieldName, simpleFillFeature as ISymbol);
                valueRender.set_Label(featureName, featureName);
                valueRender.set_Symbol(featureName, simpleFillFeature as ISymbol);

                // 获得下一组要素和颜色
                feature = featureCursor.NextFeature();
                color = enumColors.Next();
            }

            // 接口转换，对渲染方式进行设置
            IGeoFeatureLayer geoFeatureLayer = featureLayer as IGeoFeatureLayer;
            geoFeatureLayer.Renderer = valueRender as IFeatureRenderer;

            // 地图刷新
            axMapControl1.Refresh();
        }


        private void UniqueValueRendering(object sender, EventArgs e)
        {
            esriTOCControlItem tocChoosedItem = esriTOCControlItem.esriTOCControlItemLayer;
            IBasicMap basicMap = null;
            ILayer tocChoosedLayer = null;
            object other = new object();
            object index = new object();
            axTOCControl1.GetSelectedItem(
                ref tocChoosedItem,
                ref basicMap,
                ref tocChoosedLayer,
                ref other,
                ref index
            );

            if (tocChoosedLayer is IFeatureLayer)
            {
                FieldSelectDialog fieldSelectDialog = new FieldSelectDialog(tocChoosedLayer as IFeatureLayer);
                DialogResult dialogResult = fieldSelectDialog.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    defineUniqueValueRender(tocChoosedLayer as IFeatureLayer, fieldSelectDialog.selectFieldName());
                }
            }
            else
            {
                MessageBox.Show("未选择图层，或者图层非矢量图层！");
                return;
            }
        }

        private void ElementAttribute(object sender, EventArgs e)
        {
            esriTOCControlItem tocItem = esriTOCControlItem.esriTOCControlItemNone;
            IBasicMap basicMap = null;
            ILayer layer = null;
            object unk = null;
            object data = null;

            axTOCControl1.GetSelectedItem(ref tocItem, ref basicMap, ref layer, ref unk, ref data);

            if (tocItem == esriTOCControlItem.esriTOCControlItemLayer && layer is IFeatureLayer)
            {
                IFeatureLayer featureLayer = layer as IFeatureLayer;
                FeatureAttributeTable featureAttrTable = new FeatureAttributeTable(featureLayer);
                featureAttrTable.ShowDialog();
            }
            else
            {
                MessageBox.Show("请选择要素图层！");
            }
        }

        private void newMxdDocMenuItem_Click(object sender, EventArgs e)
        {
            MyMxdDocClass myDoc = new MyMxdDocClass();
            myDoc.newMapDoc(axMapControl1); 
        }

        private void openMxdDocMenuItem_Click(object sender, EventArgs e)
        {
            MyMxdDocClass myDoc = new MyMxdDocClass(); 
            myDoc.openMapDoc(axMapControl1); 
        }

        private void saveMxdDocMenuItem_Click(object sender, EventArgs e)
        {
            MyMxdDocClass myDoc = new MyMxdDocClass(); 
            myDoc.saveMapDoc(axMapControl1); 
        }

        private void saveAsMxdDocMenuItem_Click(object sender, EventArgs e)
        {
            MyMxdDocClass myDoc = new MyMxdDocClass(); 
            myDoc.SaveAsMapDoc(axMapControl1); 
        }

        private void AxTOCControl1_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
        {
            esriTOCControlItem tocControllerItem = esriTOCControlItem.esriTOCControlItemNone;
            ILayer layer = null;
            IBasicMap basicMap = null;
            object unk = null;
            object data = null;

            if (e.button == 1)
            { // 左键
                axTOCControl1.GetSelectedItem(
                    ref tocControllerItem,
                    ref basicMap,
                    ref layer,
                    ref unk,
                    ref data
                );

                if (tocControllerItem == esriTOCControlItem.esriTOCControlItemLegendClass)
                {
                    ESRI.ArcGIS.Carto.ILegendClass legendClass = new LegendClass();
                    ESRI.ArcGIS.Carto.ILegendGroup legendGroup = new LegendGroupClass();

                    if (unk is ILegendGroup)
                    {
                        legendGroup = unk as ILegendGroup;
                    }

                    legendClass = legendGroup.get_Class((int)data);
                    SymbolSelectDialog symbolSelectDilaog = new SymbolSelectDialog(legendClass, layer);
                    if (symbolSelectDilaog.ShowDialog() == DialogResult.OK)
                    {
                        legendClass.Symbol = symbolSelectDilaog.currentSymbol();
                        this.axMapControl1.ActiveView.Refresh();
                        this.axTOCControl1.Refresh();
                    }
                }
            }
        }
    }
}
